#include <stdio.h>
#include <stdlib.h>
#include <intrin.h>

int fun_int(const void *p, const void *q);
int fun_float(const void *p, const void *q);
int fun_string(const void *p, const void *q);

/*
 * 通过该程序，可以看出qsort函数，可以对各种类型的数组进行排序。
 * 由于不同类型的数据比较大小的方法不一样，
 * 因此，需要定义一个比较函数，写出比较规则。
 * 在这个例子中，定义了三个比较函数，利用qsort函数，分别对整型、浮点型、字符串数组进行了排序
 */
int main()
{
    int a[] = {98, 1, 24, 15, 78, 29, 36, 10, 91}, i;
    float b[] = {34.213, 92.123, 14, 91.231, 55, 60.345, 120.1};
    char *c[] = {"hello", "about", "who", "apple", "baname", "a", "zoo"};

    //这里要注意的是，作为参数传递就变成了指针类型
    qsort(a, sizeof(a)/sizeof(int), sizeof(int), fun_int);
    for (i = 0; i < sizeof(a)/sizeof(int); i++)
        printf("%d ", a[i]);
    printf("\n");

    qsort(b, sizeof(b)/sizeof(float), sizeof(float), fun_float);
    for (i = 0; i < sizeof(b)/sizeof(float); i++)
        printf("%f ", b[i]);
    printf("\n");

    qsort(c, sizeof(c)/sizeof(char *), sizeof(char *), fun_string);
    for (i = 0; i < sizeof(c)/sizeof(char *); i++)
        printf("%s ", c[i]);
    printf("\n");

    return 0;
}

int fun_int(const void *p, const void *q)
{
    return (*(int* const)p - *(int const *)q);
}

int fun_float(const void *p, const void *q)
{
    float t = *(float const *)p - *(float const *)q;

    //1e-6 : 1乘以10的负6次方,1e-6(也就是0.000001)叫做epslon
    //用来抵消浮点运算中因为误差造成的相等无法判断的情况,它通常是一个非常小的数字（具体多小要看你的运算误差）
    //比如说因为精度误差，用十进制举例，我们要算1/3+1/3+1/3==1（从数学上说，肯定相等），
    // 但是因为精度问题，等号左边算出来是0.3333333+0.3333333+0.3333333=0.9999999，
    //存在了误差，右边是1.0000000，那么如果直接用==，返回false，
    // 我们希望它被视作相等。那么就要两数相减取绝对值小于epslon的办法
    if (t > 1e-6)
        return 1;
    else if (t < -1e-6)
        return -1;
    else
        return 0;
}

int fun_string(const void *p, const void *q)
{
    return strcmp(*( char * const * )p, *( char * const *)q);
}